package com.idea.relax.exception.core.registry;

import com.idea.relax.exception.api.ErrorCode;
import com.idea.relax.exception.config.ExceptionKitProperties;
import com.idea.relax.exception.core.manager.ErrorCodeEnumInstance;
import com.idea.relax.exception.core.manager.InterfaceImplScanner;
import com.idea.relax.exception.core.manager.ErrorCodeManager;
import com.idea.relax.exception.api.IErrorCode;

import java.util.List;

/**
 * @author: 沉香
 * @date: 2023/5/25
 * @description: 异常码注册器
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class AutoErrorCodeRegister extends AbstractAutoErrorCodeRegister {

	private final IErrorCodeCollector codeCollector;

	private final ExceptionKitProperties properties;

	public AutoErrorCodeRegister(IErrorCodeCollector codeCollector, ExceptionKitProperties properties) {
		this.codeCollector = codeCollector;
		this.properties = properties;
	}


	@Override
	public void registry() {
		//在控制台中是否打印文档地址
		boolean isPrintDocUrl = false;
		//是否开启自定义异常码包扫描
		if (properties.isEnabledEnumScan()) {
			//扫描指定包与子包中实现IErrorCode接口的类
			List<Class> classes = InterfaceImplScanner.scanTargetSubClasses(IErrorCode.class, properties.getEnumScanPackages());
			if (!classes.isEmpty()) {
				isPrintDocUrl = true;
				for (Class cls : classes) {
					if (!cls.isEnum()) {
						continue;
					}
					//class转换为CodeEnumInstance对象
					List<ErrorCodeEnumInstance> instances = ErrorCodeManager.getCodeEnumInstance((Class<Enum>) cls);
					//注册异常码
					instances.forEach(ErrorCodeManager::register);
				}
			}
		}

		//自定义异常码收集器，收集异常码
		if (codeCollector != null) {
			ErrorCodeProvider provider = new ErrorCodeProvider();
			codeCollector.collect(provider);
			List<IErrorCode> errorCodes = provider.getErrorCodes();
			if (!errorCodes.isEmpty()) {
				isPrintDocUrl = true;
				//注册异常码
				ErrorCodeManager.register(errorCodes);
				provider.clearErrorCodes();
			}
		}

		//是否使用内置的异常码
		if (properties.isUseDefaultErrorCode()) {
			isPrintDocUrl = true;
			for (IErrorCode errorCode : ErrorCode.values()) {
				ErrorCodeManager.register(errorCode);
			}
		}

		//打印Banner到控制台
		if (isPrintDocUrl && properties.isPrintDocUri()) {
			ConsoleBannerUtil.printBanner();
		}

	}

}
